package com.tedu.ds.sessionAndMessage.rabbitMq;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.tedu.ds.sessionAndMessage.config.RabbitMQConfig;
import com.tedu.ds.sessionAndMessage.mapper.SessionAndMessageMapper;
import com.tedu.ds.sessionAndMessage.pojo.entity.SMessage;
import com.tedu.ds.sessionAndMessage.pojo.entity.WebMessage;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.io.IOException;

@Component
public class ChatListener {

    @Autowired
    private SessionAndMessageMapper sessionAndMessageMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 处理从 RabbitMQ 接收到的消息
     * @param message 消息对象
     * @param channel RabbitMQ 通道
     * @throws IOException 处理消息时可能抛出的异常
     */
    @RabbitListener(queues = "#{rabbitMQConfig.serverQueueName}", containerFactory = "rabbitListenerContainerFactory", ackMode = "MANUAL")  // 指定要监听的队列名称和手动确认模式
    public void onMessage(Message message, com.rabbitmq.client.Channel channel) throws IOException {
        try {
            String jsonMessage = new String(message.getBody(), "UTF-8");  // 将消息体转换为字符串
            WebMessage webMessage = objectMapper.readValue(jsonMessage, WebMessage.class);  // 将字符串反序列化为 WebMessage 对象
            System.out.println("接收到消息: " + webMessage);

            // 处理消息逻辑
            SMessage insertMessage = new SMessage();
            BeanUtils.copyProperties(webMessage, insertMessage);  // 将 WebMessage 对象的属性复制到 Message 对象
            insertMessage.setStatus("未读");
            sessionAndMessageMapper.insertMessage(insertMessage);  // 插入消息到数据库
            System.out.println("插入消息: " + insertMessage);

            // 手动发送确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);  // 确认消息已被处理
        } catch (IOException e) {
            e.printStackTrace();

            // 获取消息的重新交付次数
            Integer redeliveryCount = message.getMessageProperties().getHeaders().get("x-redelivered-count") != null ?
                    (Integer) message.getMessageProperties().getHeaders().get("x-redelivered-count") : 0;

            if (redeliveryCount < 3) {  // 如果重试次数小于 3 次
                // 设置重新交付次数
                message.getMessageProperties().getHeaders().put("x-redelivered-count", redeliveryCount + 1);

                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);  // 确认消息已被处理
                // 重新入队
                rabbitTemplate.send(RabbitMQConfig.EXCHANGE_NAME, RabbitMQConfig.ROUTING_KEY, message);
            } else {
                // 达到最大重试次数，发送到死信队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            }
        }
    }
}